import { fileURLToPath, URL } from "node:url";
import { ConfigEnv, defineConfig, loadEnv, UserConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { visualizer } from "rollup-plugin-visualizer";
import vueJsx from "@vitejs/plugin-vue-jsx";

type ResultMap = { [k in keyof ViteEnvOptions]: ViteEnvOptions[k] };

/**
 * @description env包裹处理类型
 * @param {Recordable} envConfig  本地配置
 * @returns {ViteEnvOptions}
 */
function wrapperEnvHandler(envConfig: Recordable): ViteEnvOptions {
  const resultMap: Record<string, unknown> = {};
  for (const key of Object.keys(envConfig)) {
    let value = envConfig[key].replace(/\\n/g, "\n");
    // 处理boolean类型
    value = value === "true" ? true : value === "false" ? false : value;
    // 处理number类型
    if (key === "VITE_PORT") value = Number(value);
    resultMap[key] = value;
  }
  return <ResultMap>resultMap;
}

export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  const root = process.cwd();
  const env = wrapperEnvHandler(loadEnv(mode, root));
  return {
    base: env.VITE_PUBLIC_PATH,
    plugins: [vue(), visualizer({ open: true }), vueJsx()],
    resolve: {
      alias: {
        "@": fileURLToPath(new URL("./src", import.meta.url))
      }
    },
    server: {
      host: "0.0.0.0",
      port: env.VITE_PORT,
      open: env.VITE_OPEN,
      cors: true,
      proxy: {
        [env.VITE_API_URL]: {
          target: env.VITE_PROXY,
          changeOrigin: true,
          rewrite: (path: string) => path.replace(new RegExp(`^${env.VITE_API_URL}`), "") // 替换请求地址中的前缀
        }
      }
    },
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@import "@/styles/var.scss";`
        }
      }
    },
    esbuild: {
      pure: env.VITE_DROP_CONSOLE ? ["console.log", "debugger"] : []
    },
    build: {
      outDir: "dist",
      minify: "terser",
      target: "es2015",
      chunkSizeWarningLimit: 2000,
      terserOptions: {
        compress: {
          drop_console: true,
          drop_debugger: true
        }
      },
      rollupOptions: {
        output: {
          chunkFileNames: "js/[hash].js",
          entryFileNames: "js/[hash].js",
          assetFileNames(assetInfo) {
            if (assetInfo.name && assetInfo.name.endsWith(".css")) {
              return "css/[hash].css";
            }
            if ([".png", "jpg", ".jpge", ".webp", ".svg", ".gif"].some((ext) => assetInfo.name && assetInfo.name.endsWith(ext))) {
              return "images/[hash].[ext]";
            }
            return "assets/[hash].[ext]";
          }
        }
      }
    }
  };
});
